<template>
  <div class="flow-chart">
    <div class="menu">
      <div class="new-rect" @mousedown="handleNewRectMousedown">
        新增
      </div>
      <div class="svg-size">
        宽度：<input class="txt-size" type="text" v-model="svgSetWidth"> px
        高度：<input class="txt-size" type="text" v-model="svgSetHeight"> px
      </div>
    </div>
    <svg ref="svg" class="svg" :width="svgWidth" :height="svgHeight" @click="handleSvgClick">
      <g @mouseover="item.coverShow=true" @mouseout="item.coverShow=false" id="rect" v-for="item in dataList" class="item-continer">
        <!-- 外层背景 -->
        <rect :x="item.x" :y="item.y" :width="itemWidth" :height="itemHeight" rx="5" fill="#1bc071" />
        <!-- 标题文字 -->
        <text :x="item.x+20" :y="item.y+20" fill="#fff">{{item.compName}}</text>
        <!-- 分配金额 -->
        <rect :x="item.x+15" :y="item.y+30" width="190" height="35" rx="3" fill="#fff"/>
        <text :x="item.x+20" :y="item.y+52" style="font-size: 12px;" fill="#5e5e5e">分配金额:</text>
        <text :x="item.x+80" :y="item.y+52" style="font-size: 12px;">￥{{item.fpje | toThousands}}</text>
        <!-- 执行金额 -->
        <rect :x="item.x+15" :y="item.y+67" width="190" height="35" rx="3" fill="#fff"/>
        <text :x="item.x+20" :y="item.y+89" style="font-size: 12px;" fill="#5e5e5e">执行金额:</text>
        <text :x="item.x+80" :y="item.y+89" style="font-size: 12px;">￥{{item.zxje  | toThousands}}</text>

        <!-- 账户信息 -->
        <rect :x="item.x+15" :y="item.y+104" width="190" height="35" rx="3" fill="#fff"/>
        <text :x="item.x+20" :y="item.y+125" style="font-size: 12px;" fill="#5e5e5e">账户信息:</text>
        <text :x="item.x+80" :y="item.y+125" style="font-size: 12px;">{{item.zhxx}}</text>

        <rect :x="item.x - 10" :y="item.y - 10" :width="itemWidth+20" :height="itemHeight+20" rx="5" fill="transparent"/>

        <!-- 遮罩 -->
        <g v-show="item.coverShow">
          <!-- 遮罩层背景 -->
          <rect :x="item.x" :y="item.y" :width="itemWidth" :height="itemHeight" rx="5" fill="rgba(13,10,49,.9)"/>
          <!-- 移动按钮(因为鼠标只能点在svg渲染图像上，下面用rect盖住将事件添加在rect上) -->
          <svg :x="item.x + itemWidth / 2 - 10" :y="item.y + itemHeight / 2 - 10" width="20" height="20" class="icon">
            <use xlink:href="#icon-yidong" fill="#fff"/>
          </svg>
          <rect @mousedown="handleMoveMD($event, item)"
            :x="item.x + itemWidth / 2 - 80" 
            :y="item.y + itemHeight / 2 - 45" 
            width="160" 
            height="90" 
            fill="transparent"
            class="move"
          />
          <!-- 表单编辑按钮 -->
          <svg :x="item.x + itemWidth - 70" :y="item.y + 10" width="20" height="20" class="icon">
            <use xlink:href="#icon-bianji" :fill="itemEditClor"/>
          </svg>
          <rect @mouseover="handleItemBtnMouseover('edit')"
            @mouseout="handleItemBtnMouseout('edit')"
            @click="handleItemBtnClick('edit', item)"
            :x="item.x + itemWidth - 70" 
            :y="item.y + 10" 
            width="20" 
            height="20" 
            fill="transparent"
            class="item-btn"
          />
          <!-- 表单删除按钮 -->
          <svg :x="item.x + itemWidth - 40" :y="item.y + 10" width="20" height="20" class="icon">
            <use xlink:href="#icon-shanchu" :fill="itemDelClor"/>
          </svg>
          <rect @mouseover="handleItemBtnMouseover('del')"
            @mouseout="handleItemBtnMouseout('del')"
            @click="handleItemBtnClick('del', item)"
            :x="item.x + itemWidth - 40" 
            :y="item.y + 10" 
            width="20" 
            height="20" 
            fill="transparent"
            class="item-btn"
          />
          <!-- 左边小圈圈 -->
          <circle :cx="item.x" :cy="item.y + itemHeight / 2"  r="4" fill="#fff" stroke="black"/>
          <circle class="move-line-circle" @mousedown="handleMoveLineMouseDown($event, 'left', item)" :cx="item.x" :cy="item.y + itemHeight / 2"  r="8" fill="transparent"/>
          <!-- 右边小圈圈 -->
          <circle :cx="item.x + itemWidth" :cy="item.y + itemHeight / 2"  r="4" fill="#fff" stroke="black"/>
          <circle class="move-line-circle" @mousedown="handleMoveLineMouseDown($event, 'right', item)" :cx="item.x + itemWidth" :cy="item.y + itemHeight / 2"  r="8" fill="transparent"/>
          <!-- 上边小圈圈 -->
          <circle :cx="item.x + itemWidth / 2" :cy="item.y"  r="4" fill="#fff" stroke="black"/>
          <circle class="move-line-circle" @mousedown="handleMoveLineMouseDown($event, 'top', item)" :cx="item.x + itemWidth / 2" :cy="item.y"  r="8" fill="transparent"/>
          <!-- 下边小圈圈 -->
          <circle :cx="item.x + itemWidth / 2" :cy="item.y + itemHeight"  r="4" fill="#fff" stroke="black"/>
          <circle class="move-line-circle" @mousedown="handleMoveLineMouseDown($event, 'bottom', item)" :cx="item.x + itemWidth / 2" :cy="item.y + itemHeight"  r="8" fill="transparent"/>
        </g>
      </g>

      <g id="line" v-for="item in lineList" class="line">
        <polyline :points="item.polyline" stroke="#ff6e97" stroke-width="4" fill="none" v-if="item.checked" />
        <!-- 起点 -->
        <circle :cx="item.x1" :cy="item.y1" r="4" fill="#999999" />
        <!-- 折线(为了方便点击加了遮罩) -->
        <polyline :points="item.polyline" stroke="#999999" stroke-width="2" fill="none" />
        <polyline :points="item.polyline" stroke="transparent" stroke-width="6" fill="none" @click="handleLineClick($event, item)" />
        <!-- 终点 -->
        <polygon :points="item.lineArrows" @mousedown="handleLineArrowsMousedown(item)" class="lineArrows" fill="#999999"/>
        <!-- 线条编辑 -->
        <g v-if="item.checked">
          <svg :x="lineDel.x+10" :y="lineDel.y+5" width="20" height="20" class="icon">
            <use xlink:href="#icon-shanchu" fill="red"/>
          </svg>
          <rect :x="lineDel.x+10" :y="lineDel.y+5" width="20" height="20" fill="transparent" @click="handleDelLine(item)"/>
        </g>
      </g>
    </svg>
  </div>
</template>

<script>
export default {
  data () {
    return {
      svgWidth: 1000,
      svgHeight: 600,
      svgSetWidth: 1000,
      svgSetHeight: 600,
      /** 元素宽度 */
      itemWidth: 220,
      /** 元素高度 */
      itemHeight: 150,
      /** 数据列表 */
      dataList: [
        {
          id: 1,
          compName: '鑫抚源',
          x: 100,
          y: 100,
          fpje: 10020000.11,
          zxje: 10020000.22,
          zhxx: '银行名称',
          coverShow: false,
          children: [
            // {
            //   id: 3,
            //   beginDrection: 'bottom',
            //   endDrection: 'left'
            // }, {
            //   id: 2,
            //   beginDrection: 'bottom',
            //   endDrection: 'left'
            // }
          ]
        },
        {
          id: 2,
          compName: '大业永顺',
          x: 600,
          y: 100,
          fpje: 10020000.00,
          zxje: 10020000.00,
          coverShow: false,
          zhxx: '交通银行上海支行',
          children: []
        },
        {
          id: 3,
          compName: '景天',
          x: 600,
          y: 300,
          fpje: 10020000.00,
          zxje: 10020000.00,
          coverShow: false,
          zhxx: '银行名称',
          children: []
        }
      ],
      /** 连接线列表 */
      lineList: [
      ],
      /** 鼠标起始位置 */
      oldMouseX: 0,
      oldMouseY: 0,
      /** 当前选中连接线 */
      currentLine: {},
      /** 当前移动表单项 */
      currentMoveItem: {},
      /** 连线起始表单项 */
      beginItem: {},
      endItem: {},
      svgTop: 0,
      svgLeft: 0,
      itemEditClor: '#fff',
      itemDelClor: '#fff',
      lineDel: {
        x: 0,
        y: 0,
        isShow: false
      }
    }
  },
  methods: {
    getLineList () {
      this.lineList.length = 0
      for (let i = 0; i < this.dataList.length; i++) {
        let children = this.dataList[i].children
        let tempDelLine = []
        if (children && children.length > 0) {
          children.forEach((childInfo, index, arr) => {
            let child = this.getChild(childInfo.id)[0]
            if (child) {
              let x2 = 0
              let y2 = 0
              if (childInfo.endDrection === 'left') {
                x2 = child.x
                y2 = child.y + this.itemHeight / 2
              } else if (childInfo.endDrection === 'right') {
                x2 = child.x + this.itemWidth
                y2 = child.y + this.itemHeight / 2
              } else if (childInfo.endDrection === 'top') {
                x2 = child.x + this.itemWidth / 2
                y2 = child.y
              } else {
                x2 = child.x + this.itemWidth / 2
                y2 = child.y + this.itemHeight
              }
              let lineObj = this.newLineObj(this.dataList[i], childInfo.beginDrection)
              lineObj.item = this.dataList[i]
              lineObj.drection = childInfo.beginDrection
              lineObj.lineId = childInfo.lineId
              this.setLineObj(this.dataList[i], lineObj, childInfo.beginDrection, child, childInfo.endDrection, x2, y2)
              // console.log(lineObj)
              this.lineList.push(lineObj)
            } else {
              tempDelLine.push(index)
            }
          })
          for (let i = tempDelLine.length - 1; i >= 0; i--) {
            children.splice(tempDelLine[i], 1)
          }
        }
      }
    },
    getChild (id) {
      return this.dataList.filter(item => {
        return item.id === id
      })
    },
    /** 移动元素 */
    handleMoveMD (event, item) {
      // this.getSvgPos()
      this.oldMouseX = event.clientX
      this.oldMouseY = event.clientY
      let oldX = item.x
      let oldY = item.y
      document.onmousemove = (ev) => {
        let moveX = ev.clientX - this.oldMouseX
        let moveY = ev.clientY - this.oldMouseY
        let currentX = oldX + moveX
        let currentY = oldY + moveY
        if (currentX < 0) {
          currentX = 0
        } else if (currentX > this.svgWidth - this.itemWidth) {
          currentX = this.svgWidth - this.itemWidth
        }

        if (currentY < 0) {
          currentY = 0
        } else if (currentY > this.svgHeight - this.itemHeight) {
          currentY = this.svgHeight - this.itemHeight
        }
        item.x = currentX
        item.y = currentY
        this.getLineList()
      }
      document.onmouseup = () => {
        document.onmousemove = null
      }
    },
    handleLineClick (ev, item) {
      ev.stopPropagation()
      this.getSvgPos()
      this.handleSvgClick()
      item.checked = true
      this.currentLine = item
      this.lineDel.x = ev.pageX - this.svgLeft - this.getScrollLeft()
      this.lineDel.y = ev.pageY - this.svgTop - this.getScrollTop()
    },
    handleSvgClick () {
      for (let i = 0; i < this.lineList.length; i++) {
        this.lineList[i].checked = false
      }
    },
    /**
        ev: event对象
        drection: 划线小圈圈的方位
        item: 小圈圈所在表单对象
     */
    handleMoveLineMouseDown (ev, drection, item) {
      this.getSvgPos()
      this.oldMouseX = event.pageX - this.svgLeft
      this.oldMouseY = event.pageY - this.svgTop
      let lineObj = this.newLineObj(item, drection)
      lineObj.item = item
      lineObj.drection = drection
      this.lineList.push(lineObj)

      document.onmousemove = (ev) => {
        // console.log(document.body.scrollTop)
        /** 鼠标相对于svg的left位置 */
        let newMouseX = ev.pageX - this.svgLeft - this.getScrollLeft()
        /** 鼠标相对于svg的top位置 */
        let newMouseY = ev.pageY - this.svgTop - this.getScrollTop()
        this.setMoveLineObj(item, lineObj, drection, newMouseX, newMouseY)
        let flag = false
        for (let i = 0; i < this.dataList.length; i++) {
          if (this.dataList[i] !== item) {
            flag = this.testImpactMoveMouse(this.dataList[i], newMouseX, newMouseY)
            if (flag) {
              this.endItem = this.dataList[i]
              break
            }
          }
        }

        if (flag) {
          let lineEndPos = this.getEndPos(this.endItem, newMouseX, newMouseY)
          let endDrection = lineEndPos.drection
          let x2 = lineEndPos.x
          let y2 = lineEndPos.y
          this.setLineObj(item, lineObj, drection, this.endItem, endDrection, x2, y2)
        }
      }

      document.onmouseup = (ev) => {
        /** 鼠标相对于svg的left位置 */
        let newMouseX = ev.pageX - this.svgLeft - this.getScrollLeft()
        /** 鼠标相对于svg的top位置 */
        let newMouseY = ev.pageY - this.svgTop - this.getScrollTop()

        /** 标记鼠标是否移入表单 */
        let flag = false
        for (let i = 0; i < this.dataList.length; i++) {
          if (this.dataList[i] !== item) {
            flag = this.testImpactMoveMouse(this.dataList[i], newMouseX, newMouseY)
            if (flag) {
              this.endItem = this.dataList[i]
              break
            }
          }
        }

        if (flag) {
          let lineEndPos = this.getEndPos(this.endItem, newMouseX, newMouseY)
          let endDrection = lineEndPos.drection
          let x2 = lineEndPos.x
          let y2 = lineEndPos.y
          let lineId = this.getLineId(item)
          this.setLineObj(item, lineObj, drection, this.endItem, endDrection, x2, y2)
          lineObj.lineId = lineId
          item.children.push({
            id: this.endItem.id,
            beginDrection: drection,
            endDrection,
            lineId
          })
        } else {
          this.lineList.pop()
        }
        document.onmousemove = null
        document.onmouseup = null
      }
    },
    getLineId (item) {
      return new Date().getTime()
    },
    /** 创建一根新的连接线 */
    newLineObj (item, begindDrection) {
      switch (begindDrection) {
        case 'left':
          return {
            x1: item.x - 4,
            y1: item.y + this.itemHeight / 2,
            lineArrows: this.getlineArrows(item.x, item.y + this.itemHeight / 2, 'left'),
            polyline: [],
            checked: false,
            item: {},
            drection: ''
          }
        case 'right':
          return {
            x1: item.x + this.itemWidth + 4,
            y1: item.y + this.itemHeight / 2,
            lineArrows: this.getlineArrows(item.x + this.itemWidth, item.y + this.itemHeight / 2, 'right'),
            polyline: [],
            checked: false,
            item: {},
            drection: ''
          }
        case 'top':
          return {
            x1: item.x + this.itemWidth / 2,
            y1: item.y - 4,
            lineArrows: this.getlineArrows(item.x + this.itemWidth / 2, item.y, 'top'),
            polyline: [],
            checked: false,
            item: {},
            drection: ''
          }
        case 'bottom':
          return {
            x1: item.x + this.itemWidth / 2,
            y1: item.y + this.itemHeight + 4,
            lineArrows: this.getlineArrows(item.x + this.itemWidth / 2, item.y, 'bottom'),
            polyline: [],
            checked: false,
            item: {},
            drection: ''
          }
        default:
          break
      }
    },
    /** 设置移动中的连接线 */
    setMoveLineObj (beginItem, lineObj, drection, x2, y2) {
      let lineArrowsDirection = this.getMovePolyline(lineObj, drection, x2, y2)
      lineObj.lineArrows = this.getlineArrows(x2, y2, lineArrowsDirection)
    },
    /** 设置移动完成后的连接线 */
    setLineObj (beginItem, lineObj, beginDrection, endItem, endDrection, x2, y2) {
      let lineArrowsDirection = this.getPolyline(beginItem, lineObj, beginDrection, endItem, endDrection, x2, y2)
      lineObj.lineArrows = this.getlineArrows(x2, y2, lineArrowsDirection)
    },
    /** 获取连接线的箭头
        ---------------------------
        params:
        x2 y2 表示连接线终点
        direction 表示箭头方向
     */
    getlineArrows (x2, y2, direction) {
      switch (direction) {
        case 'left':
          return [x2, y2, x2 + 10, y2 + 5, x2 + 10, y2 - 5].join(' ')
        case 'right':
          return [x2, y2, x2 - 10, y2 + 5, x2 - 10, y2 - 5].join(' ')
        case 'top':
          return [x2, y2, x2 + 5, y2 + 10, x2 - 5, y2 + 10].join(' ')
        case 'bottom':
          return [x2, y2, x2 + 5, y2 - 10, x2 - 5, y2 - 10].join(' ')
        default:
          break
      }
    },
    /** 获取移动中的连接线
        --------------------
        params:
        beginItem 连接线起始表单项
        lineObj 连接线对象
        drection 连接线起始表单项的小圈圈方位
        x2 y2 当前鼠标相对于svg的坐标
     */
    getMovePolyline (lineObj, drection, x2, y2) {
      let x1 = lineObj.x1
      let y1 = lineObj.y1
      let h = this.itemHeight
      let w = this.itemWidth
      if (drection === 'left') {
        if (x2 < x1) { // 当起始点在表单项左边 并且鼠标在起始点左边的时候
          if (y2 < y1 - this.itemHeight) {
            lineObj.polyline = [x1, y1, x2, y1, x2, y2].join(' ')
            return 'top'
          } else if (y2 > (y1 + this.itemHeight)) {
            lineObj.polyline = [x1, y1, x2, y1, x2, y2].join(' ')
            return 'bottom'
          } else {
            lineObj.polyline = [x1, y1, x1 + (x2 - x1) / 2, y1, x1 + (x2 - x1) / 2, y2, x2, y2].join(' ')
            return 'left'
          }
        } else if (x2 >= x1 && x2 <= x1 + w) { // 当起始点在表单项左边 并且鼠标在起始点右边的时候
          if (y2 === y1) {
            lineObj.polyline = [x1, y1, x2, y2].join(' ')
            return 'right'
          } else if (y2 < y1 - h) {
            lineObj.polyline = [x1, y1, x1 - 20, y1, x1 - 20, y2 + 20, x2, y2 + 20, x2, y2].join(' ')
            return 'top'
          } else if (y2 > (y1 + h)) {
            lineObj.polyline = [x1, y1, x1 - 20, y1, x1 - 20, y2 - 20, x2, y2 - 20, x2, y2].join(' ')
            return 'bottom'
          } else {
            lineObj.polyline = [x1, y1, x1 - 20, y1, x1 - 20, y2, x2, y2].join(' ')
            return 'right'
          }
        } else {
          if (y2 > y1 && y2 <= y1 + h / 2) {
            lineObj.polyline = [x1, y1, x1 - 20, y1, x1 - 20, y1 + h / 2 + 20, x2 - 20, y1 + h / 2 + 20, x2 - 20, y2, x2, y2].join(' ')
            return 'right'
          } else if (y2 < y1 && y2 > y1 - h / 2) {
            lineObj.polyline = [x1, y1, x1 - 20, y1, x1 - 20, y1 - h / 2 - 20, x2 - 20, y1 - h / 2 - 20, x2 - 20, y2, x2, y2].join(' ')
            return 'right'
          } else {
            lineObj.polyline = [x1, y1, x1 - 20, y1, x1 - 20, y2, x2, y2].join(' ')
            return 'right'
          }
        }
      } else if (drection === 'right') {
        if (x2 > x1) {
          if (y2 < y1 - h) {
            lineObj.polyline = [x1, y1, x2, y1, x2, y2].join(' ')
            return 'top'
          } else if (y2 > (y1 + h)) {
            lineObj.polyline = [x1, y1, x2, y1, x2, y2].join(' ')
            return 'bottom'
          } else {
            lineObj.polyline = [x1, y1, x1 + (x2 - x1) / 2, y1, x1 + (x2 - x1) / 2, y2, x2, y2].join(' ')
            return 'right'
          }
        } else if (x2 <= x1 && x2 >= x1 - w) {
          if (y2 === y1) {
            lineObj.polyline = [x1, y1, x2, y2].join(' ')
            return 'left'
          } else if (y2 < y1 - h) {
            lineObj.polyline = [x1, y1, x1 + 20, y1, x1 + 20, y2 + 20, x2, y2 + 20, x2, y2].join(' ')
            return 'top'
          } else if (y2 > (y1 + h)) {
            lineObj.polyline = [x1, y1, x1 + 20, y1, x1 + 20, y2 - 20, x2, y2 - 20, x2, y2].join(' ')
            return 'bottom'
          } else {
            lineObj.polyline = [x1, y1, x1 + 20, y1, x1 + 20, y2, x2, y2].join(' ')
            return 'left'
          }
        } else {
          if (y2 < y1 && y2 > y1 - h / 2) {
            lineObj.polyline = [x1, y1, x1 + 20, y1, x1 + 20, y1 - h / 2 - 20, x2 + 20, y1 - h / 2 - 20, x2 + 20, y2, x2, y2].join(' ')
            return 'left'
          } else if (y2 > y1 && y2 <= y1 + h / 2) {
            lineObj.polyline = [x1, y1, x1 + 20, y1, x1 + 20, y1 + h / 2 + 20, x2 + 20, y1 + h / 2 + 20, x2 + 20, y2, x2, y2].join(' ')
            return 'left'
          } else {
            lineObj.polyline = [x1, y1, x1 + 20, y1, x1 + 20, y2, x2, y2].join(' ')
            return 'left'
          }
        }
      } else if (drection === 'top') {
        if (y2 < y1) {
          if (x2 < x1 - this.itemWidth) {
            lineObj.polyline = [x1, y1, x1, y2, x2, y2].join(' ')
            return 'left'
          } else if (x2 > (x1 + this.itemWidth)) {
            lineObj.polyline = [x1, y1, x1, y2, x2, y2].join(' ')
            return 'right'
          } else {
            lineObj.polyline = [x1, y1, x1, y1 + (y2 - y1) / 2, x2, y1 + (y2 - y1) / 2, x2, y2].join(' ')
            return 'top'
          }
        } else if (y2 >= y1 && y2 <= y1 + h) {
          if (x2 === x1) {
            lineObj.polyline = [x1, y1, x2, y2].join(' ')
            return 'right'
          } else if (x2 < x1 - w) {
            lineObj.polyline = [x1, y1, x1, y1 - 20, x2 + 20, y1 - 20, x2 + 20, y2, x2, y2].join(' ')
            return 'left'
          } else if (x2 > (x1 + w)) {
            lineObj.polyline = [x1, y1, x1, y1 - 20, x2 - 20, y1 - 20, x2 - 20, y2, x2, y2].join(' ')
            return 'right'
          } else {
            lineObj.polyline = [x1, y1, x1, y1 - 20, x2, y1 - 20, x2, y2].join(' ')
            return 'bottom'
          }
        } else {
          if (x2 > x1 && x2 <= x1 + w / 2) {
            lineObj.polyline = [x1, y1, x1, y1 - 20, x1 + w / 2 + 20, y1 - 20, x1 + w / 2 + 20, y2 - 20, x2, y2 - 20, x2, y2].join(' ')
            return 'bottom'
          } else if (x2 < x1 && x2 > x1 - w / 2) {
            lineObj.polyline = [x1, y1, x1, y1 - 20, x1 - w / 2 - 20, y1 - 20, x1 - w / 2 - 20, y2 - 20, x2, y2 - 20, x2, y2].join(' ')
            return 'bottom'
          } else {
            lineObj.polyline = [x1, y1, x1, y1 - 20, x2, y1 - 20, x2, y2].join(' ')
            return 'bottom'
          }
        }
      } else if (drection === 'bottom') {
        if (y2 > y1) {
          if (x2 < x1 - this.itemWidth) {
            lineObj.polyline = [x1, y1, x1, y2, x2, y2].join(' ')
            return 'left'
          } else if (x2 > (x1 + this.itemWidth)) {
            lineObj.polyline = [x1, y1, x1, y2, x2, y2].join(' ')
            return 'right'
          } else {
            lineObj.polyline = [x1, y1, x1, y1 + (y2 - y1) / 2, x2, y1 + (y2 - y1) / 2, x2, y2].join(' ')
            return 'bottom'
          }
        } else if (y2 <= y1 && y2 >= y1 - h) {
          if (x2 === x1) {
            lineObj.polyline = [x1, y1, x2, y2].join(' ')
            return 'top'
          } else if (x2 < x1 - w) {
            lineObj.polyline = [x1, y1, x1, y1 + 20, x2 + 20, y1 + 20, x2 + 20, y2, x2, y2].join(' ')
            return 'left'
          } else if (x2 > (x1 + w)) {
            lineObj.polyline = [x1, y1, x1, y1 + 20, x2 - 20, y1 + 20, x2 - 20, y2, x2, y2].join(' ')
            return 'right'
          } else {
            lineObj.polyline = [x1, y1, x1, y1 + 20, x2, y1 + 20, x2, y2].join(' ')
            return 'top'
          }
        } else {
          if (x2 > x1 && x2 <= x1 + w / 2) {
            lineObj.polyline = [x1, y1, x1, y1 + 20, x1 + w / 2 + 20, y1 + 20, x1 + w / 2 + 20, y2 + 20, x2, y2 + 20, x2, y2].join(' ')
            return 'top'
          } else if (x2 < x1 && x2 > x1 - w / 2) {
            lineObj.polyline = [x1, y1, x1, y1 + 20, x1 - w / 2 - 20, y1 + 20, x1 - w / 2 - 20, y2 + 20, x2, y2 + 20, x2, y2].join(' ')
            return 'top'
          } else {
            lineObj.polyline = [x1, y1, x1, y1 + 20, x2, y1 + 20, x2, y2].join(' ')
            return 'top'
          }
        }
      }
    },
    /** 获取移动完成后的连接线 */
    getPolyline (beginItem, lineObj, beginDrection, endItem, endDrection, x2, y2) {
      let x1 = lineObj.x1
      let y1 = lineObj.y1
      let h = this.itemHeight
      let w = this.itemWidth
      if (beginItem.y + this.itemHeight < endItem.y) { // 当终点表单在起始表单下面的时候
        if (beginDrection === 'bottom') {
          if (endDrection === 'top') {
            lineObj.polyline = [x1, y1, x1, y1 + (y2 - y1) / 2, x2, y1 + (y2 - y1) / 2, x2, y2].join(' ')
            return 'bottom'
          } else if (endDrection === 'left') {
            if (x2 < x1) {
              lineObj.polyline = [x1, y1, x1, y1 + (y2 - h / 2 - y1) / 2, x2 - 20, y1 + (y2 - h / 2 - y1) / 2, x2 - 20, y2, x2, y2].join(' ')
            } else {
              lineObj.polyline = [x1, y1, x1, y2, x2, y2].join(' ')
            }
            return 'right'
          } else if (endDrection === 'right') {
            if (x2 <= x1) {
              lineObj.polyline = [x1, y1, x1, y2, x2, y2].join(' ')
            } else {
              lineObj.polyline = [x1, y1, x1, y1 + 20, x2 + 20, y1 + 20, x2 + 20, y2, x2, y2].join(' ')
            }
            return 'left'
          } else {
            if (x2 + w / 2 + 20 >= x1 && x2 < x1) {
              lineObj.polyline = [x1, y1, x1, y1 + 20, x2 + w / 2 + 20, y1 + 20, x2 + w / 2 + 20, y2 + 20, x2, y2 + 20, x2, y2].join(' ')
            } else if (x2 - w / 2 - 20 <= x1 && x2 >= x1) {
              lineObj.polyline = [x1, y1, x1, y1 + 20, x2 - w / 2 - 20, y1 + 20, x2 - w / 2 - 20, y2 + 20, x2, y2 + 20, x2, y2].join(' ')
            } else {
              lineObj.polyline = [x1, y1, x1, y2 + 20, x2, y2 + 20, x2, y2].join(' ')
            }
            return 'top'
          }
        } else if (beginDrection === 'left') {
          if (endDrection === 'top') {
            if (x2 < x1) {
              lineObj.polyline = [x1, y1, x2, y1, x2, y2].join(' ')
            } else {
              lineObj.polyline = [x1, y1, x1 - 20, y1, x1 - 20, y2 - 20, x2, y2 - 20, x2, y2].join(' ')
            }
            return 'bottom'
          } else if (endDrection === 'left') {
            if (x2 <= x1) {
              lineObj.polyline = [x1, y1, x2 - 20, y1, x2 - 20, y2, x2, y2].join(' ')
            } else {
              lineObj.polyline = [x1, y1, x1 - 20, y1, x1 - 20, y2, x2, y2].join(' ')
            }
            return 'right'
          } else if (endDrection === 'right') {
            if (x2 < x1) {
              lineObj.polyline = [x1, y1, x1 + (x2 - x1) / 2, y1, x1 + (x2 - x1) / 2, y2, x2, y2].join(' ')
            } else {
              lineObj.polyline = [x1, y1, x1 - 20, y1, x1 - 20, y1 + (y2 - y1) / 2, x2 + 20, y1 + (y2 - y1) / 2, x2 + 20, y2, x2, y2].join(' ')
            }
            return 'left'
          } else {
            if (x2 + w / 2 < x1) {
              lineObj.polyline = [x1, y1, x1 - 20, y1, x1 - 20, y2 + 20, x2, y2 + 20, x2, y2].join(' ')
            } else if (x2 - w / 2 <= x1 && x2 + w / 2 >= x1) {
              lineObj.polyline = [x1, y1, x2 - w / 2 - 20, y1, x2 - w / 2 - 20, y2 + 20, x2, y2 + 20, x2, y2].join(' ')
            } else {
              lineObj.polyline = [x1, y1, x1 - 20, y1, x1 - 20, y2 + 20, x2, y2 + 20, x2, y2].join(' ')
            }
            return 'top'
          }
        } else if (beginDrection === 'right') {
          if (endDrection === 'top') {
            if (x2 > x1) {
              lineObj.polyline = [x1, y1, x2, y1, x2, y2].join(' ')
            } else {
              lineObj.polyline = [x1, y1, x1 + 20, y1, x1 + 20, y2 - 20, x2, y2 - 20, x2, y2].join(' ')
            }
            return 'bottom'
          } else if (endDrection === 'left') {
            if (x2 > x1) {
              lineObj.polyline = [x1, y1, x1 + (x2 - x1) / 2, y1, x1 + (x2 - x1) / 2, y2, x2, y2].join(' ')
            } else {
              lineObj.polyline = [x1, y1, x1 + 20, y1, x1 + 20, y1 + (y2 - y1) / 2, x2 - 20, y1 + (y2 - y1) / 2, x2 - 20, y2, x2, y2].join(' ')
            }
            return 'right'
          } else if (endDrection === 'right') {
            if (x2 > x1) {
              lineObj.polyline = [x1, y1, x2 + 20, y1, x2 + 20, y2, x2, y2].join(' ')
            } else {
              lineObj.polyline = [x1, y1, x1 + 20, y1, x1 + 20, y2, x2, y2].join(' ')
            }
            return 'left'
          } else {
            if (x2 + w / 2 < x1) {
              lineObj.polyline = [x1, y1, x1 + 20, y1, x1 + 20, y2 + 20, x2, y2 + 20, x2, y2].join(' ')
            } else if (x2 + w / 2 >= x1 && x2 - w / 2 <= x1) {
              lineObj.polyline = [x1, y1, x2 + w / 2 + 20, y1, x2 + w / 2 + 20, y2 + 20, x2, y2 + 20, x2, y2].join(' ')
            } else {
              lineObj.polyline = [x1, y1, x1 + 20, y1, x1 + 20, y2 + 20, x2, y2 + 20, x2, y2].join(' ')
            }
            return 'top'
          }
        } else {
          if (endDrection === 'top') {
            if (x2 < x1 - w / 2) {
              lineObj.polyline = [x1, y1, x1, y1 - 20, x2, y1 - 20, x2, y2].join(' ')
            } else if (x2 >= x1 - w / 2 - 20 && x2 <= x1) {
              lineObj.polyline = [x1, y1, x1, y1 - 20, x1 - w / 2 - 20, y1 - 20, x1 - w / 2 - 20, y2 - 20, x2, y2 - 20, x2, y2].join(' ')
            } else if (x2 <= x1 + w / 2 + 20 && x2 > x1) {
              lineObj.polyline = [x1, y1, x1, y1 - 20, x1 + w / 2 + 20, y1 - 20, x1 + w / 2 + 20, y2 - 20, x2, y2 - 20, x2, y2].join(' ')
            } else {
              lineObj.polyline = [x1, y1, x1, y1 - 20, x2, y1 - 20, x2, y2].join(' ')
            }
            return 'bottom'
          } else if (endDrection === 'left') {
            if (x2 <= x1 - w / 2) {
              lineObj.polyline = [x1, y1, x1, y1 - 20, x2 - 20, y1 - 20, x2 - 20, y2, x2, y2].join(' ')
            } else if (x2 > x1 - w / 2 && x2 < x1 + w / 2) {
              lineObj.polyline = [x1, y1, x1, y1 - 20, x1 - w / 2 - 20, y1 - 20, x1 - w / 2 - 20, y2, x2, y2].join(' ')
            } else {
              lineObj.polyline = [x1, y1, x1, y1 - 20, x2 - 20, y1 - 20, x2 - 20, y2, x2, y2].join(' ')
            }
            return 'right'
          } else if (endDrection === 'right') {
            if (x2 <= x1 - w / 2) {
              lineObj.polyline = [x1, y1, x1, y1 - 20, x2 + 20, y1 - 20, x2 + 20, y2, x2, y2].join(' ')
            } else if (x2 > x1 - w / 2 && x2 < x1 + w / 2) {
              lineObj.polyline = [x1, y1, x1, y1 - 20, x1 + w / 2 + 20, y1 - 20, x1 + w / 2 + 20, y2, x2, y2].join(' ')
            } else {
              lineObj.polyline = [x1, y1, x1, y1 - 20, x2 + 20, y1 - 20, x2 + 20, y2, x2, y2].join(' ')
            }
            return 'left'
          } else {
            if (x2 <= x1 - w) {
              lineObj.polyline = [x1, y1, x1, y1 - 20, x1 - (x1 - x2) / 2, y1 - 20, x1 - (x1 - x2) / 2, y2 + 20, x2, y2 + 20, x2, y2].join(' ')
            } else if (x2 > x1 - w && x2 < x1) {
              lineObj.polyline = [x1, y1, x1, y1 - 20, x2 - w / 2 - 20, y1 - 20, x2 - w / 2 - 20, y2 + 20, x2, y2 + 20, x2, y2].join(' ')
            } else if (x2 >= x1 && x2 < x1 + w) {
              lineObj.polyline = [x1, y1, x1, y1 - 20, x2 + w / 2 + 20, y1 - 20, x2 + w / 2 + 20, y2 + 20, x2, y2 + 20, x2, y2].join(' ')
            } else {
              lineObj.polyline = [x1, y1, x1, y1 - 20, x1 + (x2 - x1) / 2, y1 - 20, x1 + (x2 - x1) / 2, y2 + 20, x2, y2 + 20, x2, y2].join(' ')
            }
            return 'top'
          }
        }
      } else if (beginItem.y > endItem.y + this.itemHeight) {
        if (beginDrection === 'top') {
          if (endDrection === 'bottom') {
            lineObj.polyline = [x1, y1, x1, y1 - (y1 - y2) / 2, x2, y1 - (y1 - y2) / 2, x2, y2].join(' ')
            return 'top'
          } else if (endDrection === 'left') {
            if (x2 <= x1) {
              lineObj.polyline = [x1, y1, x1, y1 - 20, x2 - 20, y1 - 20, x2 - 20, y2, x2, y2].join(' ')
            } else {
              lineObj.polyline = [x1, y1, x1, y2, x2, y2].join(' ')
            }
            return 'right'
          } else if (endDrection === 'right') {
            if (x2 < x1) {
              lineObj.polyline = [x1, y1, x1, y2, x2, y2].join(' ')
            } else {
              lineObj.polyline = [x1, y1, x1, y1 - 20, x2 + 20, y1 - 20, x2 + 20, y2, x2, y2].join(' ')
            }
            return 'left'
          } else {
            if (x2 + w / 2 <= x1 - 20) {
              lineObj.polyline = [x1, y1, x1, y2 - 20, x2, y2 - 20, x2, y2].join(' ')
            } else if (x2 + w / 2 + 20 > x1 && x2 <= x1) {
              lineObj.polyline = [x1, y1, x1, y1 - 20, x2 + w / 2 + 20, y1 - 20, x2 + w / 2 + 20, y2 - 20, x2, y2 - 20, x2, y2].join()
            } else if (x2 > x1 && x2 - w / 2 - 20 < x1) {
              lineObj.polyline = [x1, y1, x1, y1 - 20, x2 - w / 2 - 20, y1 - 20, x2 - w / 2 - 20, y2 - 20, x2, y2 - 20, x2, y2].join(' ')
            } else {
              lineObj.polyline = [x1, y1, x1, y2 - 20, x2, y2 - 20, x2, y2].join(' ')
            }
            return 'bottom'
          }
        } else if (beginDrection === 'left') {
          if (endDrection === 'bottom') {
            if (x2 < x1) {
              lineObj.polyline = [x1, y1, x2, y1, x2, y2].join(' ')
            } else {
              lineObj.polyline = [x1, y1, x1 - 20, y1, x1 - 20, y2 + 20, x2, y2 + 20, x2, y2].join(' ')
            }
            return 'top'
          } else if (endDrection === 'left') {
            if (x2 >= x1) {
              lineObj.polyline = [x1, y1, x1 - 20, y1, x1 - 20, y2, x2, y2].join(' ')
            } else {
              lineObj.polyline = [x1, y1, x2 - 20, y1, x2 - 20, y2, x2, y2].join(' ')
            }
            return 'right'
          } else if (endDrection === 'right') {
            if (x2 >= x1) {
              lineObj.polyline = [x1, y1, x1 - 20, y1, x1 - 20, y2 + (y1 - y2) / 2, x2 + 20, y2 + (y1 - y2) / 2, x2 + 20, y2, x2, y2].join(' ')
            } else {
              lineObj.polyline = [x1, y1, x2 + (x1 - x2) / 2, y1, x2 + (x1 - x2) / 2, y2, x2, y2].join(' ')
            }
            return 'left'
          } else {
            if (x2 - w / 2 >= x1) {
              lineObj.polyline = [x1, y1, x1 - 20, y1, x1 - 20, y2 - 20, x2, y2 - 20, x2, y2].join(' ')
            } else if (x2 - w / 2 < x1 && x2 + w / 2 > x1) {
              lineObj.polyline = [x1, y1, x2 - w / 2 - 20, y1, x2 - w / 2 - 20, y2 - 20, x2, y2 - 20, x2, y2].join(' ')
            } else {
              lineObj.polyline = [x1, y1, x1 - 20, y1, x1 - 20, y2 - 20, x2, y2 - 20, x2, y2].join(' ')
            }
            return 'bottom'
          }
        } else if (beginDrection === 'right') {
          if (endDrection === 'bottom') {
            if (x2 > x1) {
              lineObj.polyline = [x1, y1, x2, y1, x2, y2].join(' ')
            } else {
              lineObj.polyline = [x1, y1, x1 + 20, y1, x1 + 20, y2 + 20, x2, y2 + 20, x2, y2].join(' ')
            }
            return 'top'
          } else if (endDrection === 'left') {
            if (x2 > x1) {
              lineObj.polyline = [x1, y1, x1 + (x2 - x1) / 2, y1, x1 + (x2 - x1) / 2, y2, x2, y2].join(' ')
            } else {
              lineObj.polyline = [x1, y1, x1 + 20, y1, x1 + 20, y2 + (y1 - y2) / 2, x2 - 20, y2 + (y1 - y2) / 2, x2 - 20, y2, x2, y2].join(' ')
            }
            return 'right'
          } else if (endDrection === 'right') {
            if (x2 >= x1) {
              lineObj.polyline = [x1, y1, x2 + 20, y1, x2 + 20, y2, x2, y2].join(' ')
            } else if (x2 < x1) {
              lineObj.polyline = [x1, y1, x1 + 20, y1, x1 + 20, y2, x2, y2].join(' ')
            }
            return 'left'
          } else {
            if (x2 - w / 2 > x1) {
              lineObj.polyline = [x1, y1, x1 + 20, y1, x1 + 20, y2 - 20, x2, y2 - 20, x2, y2].join(' ')
            } else if (x2 - w / 2 <= x1 && x2 + w / 2 >= x1) {
              lineObj.polyline = [x1, y1, x2 + w / 2 + 20, y1, x2 + w / 2 + 20, y2 - 20, x2, y2 - 20, x2, y2].join(' ')
            } else {
              lineObj.polyline = [x1, y1, x1 + 20, y1, x1 + 20, y2 - 20, x2, y2 - 20, x2, y2].join(' ')
            }
            return 'bottom'
          }
        } else {
          if (endDrection === 'bottom') {
            if (x2 > x1 + w / 2 + 20) {
              lineObj.polyline = [x1, y1, x1, y1 + 20, x2, y1 + 20, x2, y2].join(' ')
            } else if (x2 < x1 + w / 2 + 20 && x2 >= x1) {
              lineObj.polyline = [x1, y1, x1, y1 + 20, x1 + w / 2 + 20, y1 + 20, x1 + w / 2 + 20, y2 + 20, x2, y2 + 20, x2, y2].join(' ')
            } else if (x2 < x1 && x2 >= x1 - w / 2 - 20) {
              lineObj.polyline = [x1, y1, x1, y1 + 20, x1 - w / 2 - 20, y1 + 20, x1 - w / 2 - 20, y2 + 20, x2, y2 + 20, x2, y2].join(' ')
            } else {
              lineObj.polyline = [x1, y1, x1, y1 + 20, x2, y1 + 20, x2, y2].join(' ')
            }
            return 'top'
          } else if (endDrection === 'left') {
            if (x2 > x1 + w / 2) {
              lineObj.polyline = [x1, y1, x1, y1 + 20, x2 - 20, y1 + 20, x2 - 20, y2, x2, y2].join(' ')
            } else if (x2 <= x1 + w / 2 && x2 >= x1 - w / 2) {
              lineObj.polyline = [x1, y1, x1, y1 + 20, x1 - w / 2 - 20, y1 + 20, x1 - w / 2 - 20, y2, x2, y2].join(' ')
            } else {
              lineObj.polyline = [x1, y1, x1, y1 + 20, x2 - 20, y1 + 20, x2 - 20, y2, x2, y2].join(' ')
            }
            return 'right'
          } else if (endDrection === 'right') {
            if (x2 >= x1 + w / 2) {
              lineObj.polyline = [x1, y1, x1, y1 + 20, x2 + 20, y1 + 20, x2 + 20, y2, x2, y2].join(' ')
            } else if (x2 < x1 + w / 2 && x2 > x1 - w / 2) {
              lineObj.polyline = [x1, y1, x1, y1 + 20, x1 + w / 2 + 20, y1 + 20, x1 + w / 2 + 20, y2, x2, y2].join(' ')
            } else {
              lineObj.polyline = [x1, y1, x1, y1 + 20, x2 + 20, y1 + 20, x2 + 20, y2, x2, y2].join(' ')
            }
            return 'left'
          } else {
            if (x2 > x1 + w) {
              lineObj.polyline = [x1, y1, x1, y1 + 20, x1 + (x2 - x1) / 2, y1 + 20, x1 + (x2 - x1) / 2, y2 - 20, x2, y2 - 20, x2, y2].join(' ')
            } else if (x2 <= x1 + w && x2 > x1) {
              lineObj.polyline = [x1, y1, x1, y1 + 20, x1 - w / 2 - 20, y1 + 20, x1 - w / 2 - 20, y2 - 20, x2, y2 - 20, x2, y2].join(' ')
            } else if (x2 <= x1 && x2 > x1 - w) {
              lineObj.polyline = [x1, y1, x1, y1 + 20, x1 + w / 2 + 20, y1 + 20, x1 + w / 2 + 20, y2 - 20, x2, y2 - 20, x2, y2].join(' ')
            } else {
              lineObj.polyline = [x1, y1, x1, y1 + 20, x2 + (x1 - x2) / 2, y1 + 20, x2 + (x1 - x2) / 2, y2 - 20, x2, y2 - 20, x2, y2].join(' ')
            }
            return 'bottom'
          }
        }
      } else if (beginItem.x + this.itemWidth < endItem.x) {
        if (beginDrection === 'right') {
          if (endDrection === 'left') {
            lineObj.polyline = [x1, y1, x1 + (x2 - x1) / 2, y1, x1 + (x2 - x1) / 2, y2, x2, y2].join(' ')
            return 'right'
          } else if (endDrection === 'top') {
            if (y1 < y2) {
              lineObj.polyline = [x1, y1, x2, y1, x2, y2].join(' ')
            } else {
              lineObj.polyline = [x1, y1, x1 + 20, y1, x1 + 20, y2 - 20, x2, y2 - 20, x2, y2].join(' ')
            }
            return 'bottom'
          } else if (endDrection === 'bottom') {
            if (y1 < y2) {
              lineObj.polyline = [x1, y1, x1 + 20, y1, x1 + 20, y2 + 20, x2, y2 + 20, x2, y2].join(' ')
            } else {
              lineObj.polyline = [x1, y1, x2, y1, x2, y2].join(' ')
            }
            return 'top'
          } else {
            if (y1 < y2 - h / 2 - 20 || y1 > y2 + h / 2 + 20) {
              lineObj.polyline = [x1, y1, x2 + 20, y1, x2 + 20, y2, x2, y2].join(' ')
            } else if (y1 < y2) {
              lineObj.polyline = [x1, y1, x1 + 20, y1, x1 + 20, y2 - h / 2 - 20, x2 + 20, y2 - h / 2 - 20, x2 + 20, y2, x2, y2].join(' ')
            } else {
              lineObj.polyline = [x1, y1, x1 + 20, y1, x1 + 20, y2 + h / 2 + 20, x2 + 20, y2 + h / 2 + 20, x2 + 20, y2, x2, y2].join(' ')
            }
            return 'left'
          }
        } else if (beginDrection === 'top') {
          if (endDrection === 'left') {
            if (y1 < y2) {
              lineObj.polyline = [x1, y1, x1, y1 - 20, x2 - 20, y1 - 20, x2 - 20, y2, x2, y2].join(' ')
            } else {
              lineObj.polyline = [x1, y1, x1, y2, x2, y2].join(' ')
            }
            return 'right'
          } else if (endDrection === 'top') {
            if (y1 < y2) {
              lineObj.polyline = [x1, y1, x1, y1 - 20, x2, y1 - 20, x2, y2].join(' ')
            } else {
              lineObj.polyline = [x1, y1, x1, y2 - 20, x2, y2 - 20, x2, y2].join(' ')
            }
            return 'bottom'
          } else if (endDrection === 'bottom') {
            lineObj.polyline = [x1, y1, x1, y1 - 20, x1 + (x2 - x1) / 2, y1 - 20, x1 + (x2 - x1) / 2, y2 + 20, x2, y2 + 20, x2, y2].join(' ')
            return 'top'
          } else {
            if (y1 < y2 - h / 2) {
              lineObj.polyline = [x1, y1, x1, y1 - 20, x2 + 20, y1 - 20, x2 + 20, y2, x2, y2].join(' ')
            } else {
              lineObj.polyline = [x1, y1, x1, y2 - h / 2 - 20, x2 + 20, y2 - h / 2 - 20, x2 + 20, y2, x2, y2].join(' ')
            }
            return 'left'
          }
        } else if (beginDrection === 'bottom') {
          if (endDrection === 'left') {
            if (y1 < y2) {
              lineObj.polyline = [x1, y1, x1, y2, x2, y2].join(' ')
            } else {
              lineObj.polyline = [x1, y1, x1, y1 + 20, x2 - 20, y1 + 20, x2 - 20, y2, x2, y2].join(' ')
            }
            return 'right'
          } else if (endDrection === 'top') {
            lineObj.polyline = [x1, y1, x1, y1 + 20, x1 + (x2 - x1) / 2, y1 + 20, x1 + (x2 - x1) / 2, y2 - 20, x2, y2 - 20, x2, y2].join(' ')
            return 'bottom'
          } else if (endDrection === 'bottom') {
            if (y1 < y2) {
              lineObj.polyline = [x1, y1, x1, y2 + 20, x2, y2 + 20, x2, y2].join(' ')
            } else {
              lineObj.polyline = [x1, y1, x1, y1 + 20, x2, y1 + 20, x2, y2].join(' ')
            }
            return 'top'
          } else {
            if (y1 < y2 + h / 2) {
              lineObj.polyline = [x1, y1, x1, y2 + h / 2 + 20, x2 + 20, y2 + h / 2 + 20, x2 + 20, y2, x2, y2].join(' ')
            } else {
              lineObj.polyline = [x1, y1, x1, y1 + 20, x2 + 20, y1 + 20, x2 + 20, y2, x2, y2].join(' ')
            }
            return 'left'
          }
        } else {
          if (endDrection === 'left') {
            if (y2 > y1 && y1 + h / 2 + 20 >= y2) {
              lineObj.polyline = [x1, y1, x1 - 20, y1, x1 - 20, y1 + h / 2 + 20, x2 - 20, y1 + h / 2 + 20, x2 - 20, y2, x2, y2].join(' ')
            } else if (y2 <= y1 && y1 - h / 2 - 20 <= y2) {
              lineObj.polyline = [x1, y1, x1 - 20, y1, x1 - 20, y1 - h / 2 - 20, x2 - 20, y1 - h / 2 - 20, x2 - 20, y2, x2, y2].join(' ')
            } else {
              lineObj.polyline = [x1, y1, x1 - 20, y1, x1 - 20, y2, x2, y2].join(' ')
            }
            return 'right'
          } else if (endDrection === 'top') {
            if (y1 - h / 2 < y2) {
              lineObj.polyline = [x1, y1, x1 - 20, y1, x1 - 20, y1 - h / 2 - 20, x2, y1 - h / 2 - 20, x2, y2].join(' ')
            } else {
              lineObj.polyline = [x1, y1, x1 - 20, y1, x1 - 20, y2 - 20, x2, y2 - 20, x2, y2].join(' ')
            }
            return 'bottom'
          } else if (endDrection === 'bottom') {
            if (y1 + h / 2 < y2) {
              lineObj.polyline = [x1, y1, x1 - 20, y1, x1 - 20, y2 + 20, x2, y2 + 20, x2, y2].join(' ')
            } else {
              lineObj.polyline = [x1, y1, x1 - 20, y1, x1 - 20, y1 + h / 2 + 20, x2, y1 + h / 2 + 20, x2, y2].join(' ')
            }
            return 'top'
          } else {
            if (y1 < y2) {
              lineObj.polyline = [x1, y1, x1 - 20, y1, x1 - 20, y1 - h / 2 - 20, x2 + 20, y1 - h / 2 - 20, x2 + 20, y2, x2, y2].join(' ')
            } else {
              lineObj.polyline = [x1, y1, x1 - 20, y1, x1 - 20, y1 + h / 2 + 20, x2 + 20, y1 + h / 2 + 20, x2 + 20, y2, x2, y2].join(' ')
            }
            return 'left'
          }
        }
      } else if (beginItem.x > endItem.x + this.itemWidth) {
        if (beginDrection === 'left') {
          if (endDrection === 'right') {
            lineObj.polyline = [x1, y1, x2 + (x1 - x2) / 2, y1, x2 + (x1 - x2) / 2, y2, x2, y2].join(' ')
            return 'left'
          } else if (endDrection === 'top') {
            if (y1 < y2) {
              lineObj.polyline = [x1, y1, x2, y1, x2, y2].join(' ')
            } else {
              lineObj.polyline = [x1, y1, x1 - 20, y1, x1 - 20, y2 - 20, x2, y2 - 20, x2, y2].join(' ')
            }
            return 'bottom'
          } else if (endDrection === 'bottom') {
            if (y1 < y2) {
              lineObj.polyline = [x1, y1, x1 - 20, y1, x1 - 20, y2 + 20, x2, y2 + 20, x2, y2].join(' ')
            } else {
              lineObj.polyline = [x1, y1, x2, y1, x2, y2].join(' ')
            }
            return 'top'
          } else {
            if (y1 < y2 - h / 2 - 20 || y1 > y2 + h / 2 + 20) {
              lineObj.polyline = [x1, y1, x2 - 20, y1, x2 - 20, y2, x2, y2].join(' ')
            } else if (y1 < y2) {
              lineObj.polyline = [x1, y1, x1 - 20, y1, x1 - 20, y2 - h / 2 - 20, x2 - 20, y2 - h / 2 - 20, x2 - 20, y2, x2, y2].join(' ')
            } else {
              lineObj.polyline = [x1, y1, x1 - 20, y1, x1 - 20, y2 + h / 2 + 20, x2 - 20, y2 + h / 2 + 20, x2 - 20, y2, x2, y2].join(' ')
            }
            return 'right'
          }
        } else if (beginDrection === 'top') {
          if (endDrection === 'right') {
            if (y1 < y2) {
              lineObj.polyline = [x1, y1, x1, y1 - 20, x2 + 20, y1 - 20, x2 + 20, y2, x2, y2].join(' ')
            } else {
              lineObj.polyline = [x1, y1, x1, y2, x2, y2].join(' ')
            }
            return 'left'
          } else if (endDrection === 'top') {
            if (y1 < y2) {
              lineObj.polyline = [x1, y1, x1, y1 - 20, x2, y1 - 20, x2, y2].join(' ')
            } else {
              lineObj.polyline = [x1, y1, x1, y2 - 20, x2, y2 - 20, x2, y2].join(' ')
            }
            return 'bottom'
          } else if (endDrection === 'bottom') {
            lineObj.polyline = [x1, y1, x1, y1 - 20, x2 + (x1 - x2) / 2, y1 - 20, x2 + (x1 - x2) / 2, y2 + 20, x2, y2 + 20, x2, y2].join(' ')
            return 'top'
          } else {
            if (y1 > y2 - h / 2) {
              lineObj.polyline = [x1, y1, x1, y2 - h / 2 - 20, x2 - 20, y2 - h / 2 - 20, x2 - 20, y2, x2, y2].join(' ')
            } else {
              lineObj.polyline = [x1, y1, x1, y1 - 20, x2 - 20, y1 - 20, x2 - 20, y2, x2, y2].join(' ')
            }
            return 'right'
          }
        } else if (beginDrection === 'bottom') {
          if (endDrection === 'right') {
            if (y1 < y2) {
              lineObj.polyline = [x1, y1, x1, y2, x2, y2].join(' ')
            } else {
              lineObj.polyline = [x1, y1, x1, y1 + 20, x2 + 20, y1 + 20, x2 + 20, y2, x2, y2].join(' ')
            }
            return 'left'
          } else if (endDrection === 'top') {
            lineObj.polyline = [x1, y1, x1, y1 + 20, x2 + (x1 - x2) / 2, y1 + 20, x2 + (x1 - x2) / 2, y2 - 20, x2, y2 - 20, x2, y2].join(' ')
            return 'bottom'
          } else if (endDrection === 'bottom') {
            if (y1 < y2) {
              lineObj.polyline = [x1, y1, x1, y2 + 20, x2, y2 + 20, x2, y2].join(' ')
            } else {
              lineObj.polyline = [x1, y1, x1, y1 + 20, x2, y1 + 20, x2, y2].join(' ')
            }
            return 'top'
          } else {
            if (y1 < y2 + h / 2) {
              lineObj.polyline = [x1, y1, x1, y2 + h / 2 + 20, x2 - 20, y2 + h / 2 + 20, x2 - 20, y2, x2, y2].join(' ')
            } else {
              lineObj.polyline = [x1, y1, x1, y1 + 20, x2 - 20, y1 + 20, x2 - 20, y2, x2, y2].join(' ')
            }
            return 'right'
          }
        } else {
          if (endDrection === 'right') {
            if (y2 > y1 && y1 + h / 2 + 20 >= y2) {
              lineObj.polyline = [x1, y1, x1 + 20, y1, x1 + 20, y1 + h / 2 + 20, x2 + 20, y1 + h / 2 + 20, x2 + 20, y2, x2, y2].join(' ')
            } else if (y2 <= y1 && y1 - h / 2 - 20 <= y2) {
              lineObj.polyline = [x1, y1, x1 + 20, y1, x1 + 20, y1 - h / 2 - 20, x2 + 20, y1 - h / 2 - 20, x2 + 20, y2, x2, y2].join(' ')
            } else {
              lineObj.polyline = [x1, y1, x1 + 20, y1, x1 + 20, y2, x2, y2].join(' ')
            }
            return 'left'
          } else if (endDrection === 'top') {
            if (y1 - h / 2 < y2) {
              lineObj.polyline = [x1, y1, x1 + 20, y1, x1 + 20, y1 - h / 2 - 20, x2, y1 - h / 2 - 20, x2, y2].join(' ')
            } else {
              lineObj.polyline = [x1, y1, x1 + 20, y1, x1 + 20, y2 - 20, x2, y2 - 20, x2, y2].join(' ')
            }
            return 'bottom'
          } else if (endDrection === 'bottom') {
            if (y1 + h / 2 < y2) {
              lineObj.polyline = [x1, y1, x1 + 20, y1, x1 + 20, y2 + 20, x2, y2 + 20, x2, y2].join(' ')
            } else {
              lineObj.polyline = [x1, y1, x1 + 20, y1, x1 + 20, y1 + h / 2 + 20, x2, y1 + h / 2 + 20, x2, y2].join(' ')
            }
            return 'top'
          } else {
            if (y1 < y2) {
              lineObj.polyline = [x1, y1, x1 + 20, y1, x1 + 20, y2 + h / 2 + 20, x2 - 20, y2 + h / 2 + 20, x2 - 20, y2, x2, y2].join(' ')
            } else {
              lineObj.polyline = [x1, y1, x1 + 20, y1, x1 + 20, y2 - h / 2 - 20, x2 - 20, y2 - h / 2 - 20, x2 - 20, y2, x2, y2].join(' ')
            }
            return 'right'
          }
        }
      } else {
        lineObj.polyline = [x1, y1, x2, y2].join()
        return ''
      }
    },
    /** 移动箭头碰撞检测
        ---------------------
        item 表单元素
        x2 y2 鼠标当前坐标位置
     */
    testImpactMoveMouse (item, x2, y2) {
      if (x2 > item.x - 10 && x2 < item.x + this.itemWidth + 10 && y2 > item.y - 10 && y2 < item.y + this.itemHeight + 10) {
        item.coverShow = true
        return true
      }

      return false
    },
    /** 后去移动完成后的连接线的终点坐标以及在终点对象的上的方位 */
    getEndPos (item, x2, y2) {
      let qqList = [
        {
          x: item.x,
          y: item.y + this.itemHeight / 2,
          drection: 'left'
        },
        {
          x: item.x + this.itemWidth,
          y: item.y + this.itemHeight / 2,
          drection: 'right'
        },
        {
          x: item.x + this.itemWidth / 2,
          y: item.y,
          drection: 'top'
        },
        {
          x: item.x + this.itemWidth / 2,
          y: item.y + this.itemHeight,
          drection: 'bottom'
        }
      ]

      qqList.sort(function (a, b) {
        return Math.sqrt(Math.pow(x2 - a.x, 2) + Math.pow(y2 - a.y, 2)) - Math.sqrt(Math.pow(x2 - b.x, 2) + Math.pow(y2 - b.y, 2))
      })

      return qqList[0]
    },
    getSvgPos () {
      this.svgTop = this.$refs.svg.getBoundingClientRect().top
      this.svgLeft = this.$refs.svg.getBoundingClientRect().left
    },
    handleNewRectMousedown (e) {
      this.getSvgPos()
      let newDiv = document.createElement('div')
      newDiv.setAttribute('class', 'new-rect')
      newDiv.style.position = 'absolute'
      newDiv.style.left = e.clientX - 25 + 'px'
      newDiv.style.top = e.clientY - 15 + 'px'
      document.body.appendChild(newDiv)

      document.onmousemove = (e) => {
        let isNewRect = false
        console.log(newDiv.offsetTop + ',' + this.svgTop)
        if (newDiv.offsetTop > this.svgTop && newDiv.offsetLeft > this.svgLeft) {
          document.body.removeChild(newDiv)
          if (!isNewRect) {
            this.currentMoveItem = {
              id: this.getNewRectId(),
              compName: '大业永顺',
              x: 0,
              y: 0,
              fpje: '10,020,000.00',
              zxje: '10,020,000.00',
              coverShow: false,
              zhxx: '银行名称',
              children: []
            }
            this.dataList.push(this.currentMoveItem)
            isNewRect = true
          }
        } else {
          newDiv.style.left = e.clientX - 25 + 'px'
          newDiv.style.top = e.clientY - 15 + 'px'
        }

        let x = e.clientX - this.svgLeft - this.itemWidth / 2
        if (x < 0) x = 0
        else if (x > this.svgWidth - this.itemWidth) x = this.svgWidth - this.itemWidth
        this.currentMoveItem.x = x

        let y = e.clientY - this.svgTop - this.itemHeight / 2

        if (y < 0) y = 0
        else if (y > this.svgHeight - this.itemHeight) y = this.svgHeight - this.itemHeight
        this.currentMoveItem.y = y

        // newRect.x = e.clientX - this.svgLeft - document.body.scrollLeft
        // newRect.y = e.clickY - this.svgTop - document.body.scrollTop
      }

      document.onmouseup = (ev) => {
        document.onmousemove = null
        // console.log(newDiv.parentNode)
        if (newDiv.parentNode) {
          document.body.removeChild(newDiv)
        }

        this.currentMoveItem = {}
      }
    },
    getNewRectId () {
      return new Date().getTime()
    },
    /** 表单按钮改变颜色
     */
    handleItemBtnMouseover (val) {
      if (val === 'edit') this.itemEditClor = 'red'
      else if (val === 'del') this.itemDelClor = 'red'
    },
    handleItemBtnMouseout (val) {
      if (val === 'edit') this.itemEditClor = '#fff'
      else if (val === 'del') this.itemDelClor = '#fff'
    },
    handleItemBtnClick (val, item) {
      if (val === 'edit') this.$emit('editClick', item)
      else if (val === 'del') {
        this.dataList.splice(this.dataList.indexOf(item), 1)
        this.getLineList()
        this.$emit('delClick', item)
      }
    },
    handleLineArrowsMousedown (lineObj) {
      this.getSvgPos()
      let item = lineObj.item
      let drection = lineObj.drection
      if (this.getChildIndexByLineId(item, lineObj.lineId) >= 0) {
        item.children.splice(this.getChildIndexByLineId(item, lineObj.lineId), 1)
      }

      document.onmousemove = (ev) => {
        // console.log(document.body.scrollTop)
        /** 鼠标相对于svg的left位置 */
        let newMouseX = ev.pageX - this.svgLeft - this.getScrollLeft()
        /** 鼠标相对于svg的top位置 */
        let newMouseY = ev.pageY - this.svgTop - this.getScrollTop()
        this.setMoveLineObj(item, lineObj, drection, newMouseX, newMouseY)
        let flag = false
        for (let i = 0; i < this.dataList.length; i++) {
          if (this.dataList[i] !== item) {
            flag = this.testImpactMoveMouse(this.dataList[i], newMouseX, newMouseY)
            if (flag) {
              this.endItem = this.dataList[i]
              break
            }
          }
        }

        if (flag) {
          let lineEndPos = this.getEndPos(this.endItem, newMouseX, newMouseY)
          let endDrection = lineEndPos.drection
          let x2 = lineEndPos.x
          let y2 = lineEndPos.y
          this.setLineObj(item, lineObj, drection, this.endItem, endDrection, x2, y2)
        }
      }

      document.onmouseup = (ev) => {
        /** 鼠标相对于svg的left位置 */
        let newMouseX = ev.pageX - this.svgLeft - this.getScrollLeft()
        /** 鼠标相对于svg的top位置 */
        let newMouseY = ev.pageY - this.svgTop - this.getScrollTop()

        /** 标记鼠标是否移入表单 */
        let flag = false
        for (let i = 0; i < this.dataList.length; i++) {
          if (this.dataList[i] !== item) {
            flag = this.testImpactMoveMouse(this.dataList[i], newMouseX, newMouseY)
            if (flag) {
              this.endItem = this.dataList[i]
              break
            }
          }
        }

        if (flag) {
          let lineEndPos = this.getEndPos(this.endItem, newMouseX, newMouseY)
          console.log(lineEndPos)
          let endDrection = lineEndPos.drection
          let x2 = lineEndPos.x
          let y2 = lineEndPos.y
          this.setLineObj(item, lineObj, drection, this.endItem, endDrection, x2, y2)
          item.children.push({
            id: this.endItem.id,
            beginDrection: drection,
            endDrection,
            lineId: this.getLineId()
          })
        } else {
          for (let i = 0; i < this.lineList.length; i++) {
            if (this.lineList[i].lineId === lineObj.lineId) {
              this.lineList.splice(i, 1)
            }
          }
        }
        document.onmousemove = null
        document.onmouseup = null
        console.log(this.dataList)
      }
    },
    getChildIndexByLineId (item, lineId) {
      let temp = 0
      item.children.forEach((child, index) => {
        if (child.lineId === lineId) {
          temp = index
        }
      })
      return temp
    },
    handleDelLine (lineObj) {
      let item = lineObj.item
      item.children.splice(this.getChildIndexByLineId(item, lineObj.lineId), 1)
      this.lineList.splice(this.lineList.indexOf(lineObj), 1)
    },
    getScrollTop () {
      let scrollTop = 0
      if (document.documentElement && document.documentElement.scrollTop) {
        scrollTop = document.documentElement.scrollTop
      } else {
        scrollTop = document.body.scrollTop
      }
      return scrollTop
    },
    getScrollLeft () {
      let scrollLeft = 0
      if (document.documentElement && document.documentElement.scrollLeft) {
        scrollLeft = document.documentElement.scrollLeft
      } else {
        scrollLeft = document.body.scrollLeft
      }
      return scrollLeft
    }
  },
  created () {
    this.getLineList()
  },
  mounted () {
    document.body.scrollTop = 0
    this.getSvgPos()
  },
  watch: {
    svgSetHeight (value) {
      if (value < 600) {
        // console.log(value)
        this.svgHeight = 600
      } else {
        this.svgHeight = value
      }
    },
    svgSetWidth (value) {
      if (value < 1000) {
        this.svgWidth = 1000
      } else {
        this.svgWidth = value
      }
    }
  },
  filters: {
    toThousands (value) {
      let temp = value.toString().split('.')
      let num = (temp[0] || 0).toString()
      let result = ''
      while (num.length > 3) {
        result = ',' + num.slice(-3) + result
        num = num.slice(0, num.length - 3)
      }
      if (num) { result = num + result }
      if (temp[1]) return result + '.' + temp[1]
      else return result + '.' + '00'
    }
  }
}
</script>

<style>
.icon{
  width: 1em; height: 1em;
  vertical-align: -0.15em;
  fill: currentColor;
  overflow: hidden;
}

.flow-chart {
  padding: 0 20px;
  user-select: none;
}

.menu {
  height: 60px;
  padding-top: 14px;
  box-sizing: border-box;
}

.new-rect{
  float: left;
  width: 50px;
  height: 30px;
  line-height: 30px;
  border: 1px solid #ccc;
  text-align: center;
  font-size: 14px;
}

.new-rect:hover {
  cursor: move;
}

.svg-size {
  float: left;
  margin: 4px 0 0 20px;
  font-size: 14px;
}

.txt-size {
  width: 50px;
  
}

.svg {
  border: 1px solid #ccc;
  /* 无法选中文字 */
  user-select: none;
}

.move:hover{
  cursor: move;
}

.line:hover{
  cursor:pointer;
}

.lineArrows{
  cursor:move;
}

.move-line-circle:hover {
  cursor: crosshair;
}

.move-line-circle:hover .cover{
  display:block;
}

.item-btn:hover {
  cursor:pointer;
}
</style>
 